/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package interfacesGraficas;

import DTOs.DTOMaterial;
import DTOs.DTOProveedor;
import Fabricas.FabricaExpertos;
import entidadesNegocio.DetalleListaMateriales;
import entidadesNegocio.ListaMateriales;
import entidadesNegocio.Material;
import entidadesNegocio.Proveedor;
import excepciones.ExpertoMaterialesException;
import excepciones.ExpertoProveedoresException;
import expertos.ExpertoMateriales;
import expertos.ExpertoProveedores;
import interfacesGraficas.JDialogs.ControladorProveedoresNuevaListaMateriales;
import interfacesGraficas.ModeloCombo.ModeloComboBoxTiposMat;
import interfacesGraficas.ModeloTablas.ModeloTablaListaMateriales;
import interfacesGraficas.ModeloTablas.ModeloTablaMaterialesNombre;
import interfacesGraficas.ModeloTablas.ModeloTablaProveedores;
import java.awt.Color;
import java.awt.Component;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JInternalFrame;
import javax.swing.JOptionPane;
import javax.swing.JTextField;
import utilidades.formateadorfechas;
import utilidades.tablas.RenderTablaListaMaterialesProveedor;

/**
 *
 * @author diego
 */
public class ControladorProveedores extends Controlador {

    private PantallaProveedoresNew pantalla;
    private PantallaProveedoresNuevoProv pantallaModificarProv;
    private ExpertoProveedores experto;
    private ModeloTablaProveedores modeloTablaProveedores;
    //****panel lista materiales prooovedor
    private ModeloTablaListaMateriales modeloTablaListaMateriales;
    private List<Material> materialesParaAgregar; //Aquí estan todos los materiales, que se pueden agregar a la lista del proveedor
    private ModeloTablaMaterialesNombre modelotablaAgregarMateriales;//Modelo de tabla de los materiales que se pueden agregar
    private ModeloComboBoxTiposMat modeloComboTiposMat;
    //***panel Nueva Lista Materiales
    ControladorProveedoresNuevaListaMateriales controladorNuevaListaMateriales;
    //***respaldo jtabbedMateriales
    private Component respaldoJtabbed;

    public ControladorProveedores() {
        pantalla = new PantallaProveedoresNew();
        pantallaModificarProv = new PantallaProveedoresNuevoProv();
        experto = (ExpertoProveedores) FabricaExpertos.getInstancia().getExperto(FabricaExpertos.expertos.PROVEEDORES);
        controladorNuevaListaMateriales = new ControladorProveedoresNuevaListaMateriales(experto, this);


        modeloTablaProveedores = new ModeloTablaProveedores();
        pantalla.getTblProveedores().setModel(modeloTablaProveedores);
        pantalla.getTblProveedores().setAutoCreateRowSorter(true);

        modeloTablaListaMateriales = new ModeloTablaListaMateriales();
        pantalla.getTblListaMateriales().setModel(modeloTablaListaMateriales);
        pantalla.getTblListaMateriales().setAutoCreateRowSorter(false);


        pantalla.getTblListaMateriales().setDefaultRenderer(Object.class, new RenderTablaListaMaterialesProveedor());
        modelotablaAgregarMateriales = new ModeloTablaMaterialesNombre();
        pantalla.getTblMateriales().setModel(modelotablaAgregarMateriales);

        //boton buscar
        pantalla.getBtnBuscar().addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                buscarProveedores();
            }
        });
        //boton nuevo proveedor
        pantalla.getBtnNuevoProveedor().addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                nuevoProveedor();
            }
        });
        //boton modificar proveedor
        pantalla.getBtnModificarProveedor().addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                modificarProveedorSeleccionado();
            }
        });
        //boton eliminar Proveedor
        pantalla.getBtnEliminarProveedor().addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                eliminarProveedor();
            }
        });
        //tabla proveedores, selecciona el proveedor que se cliquea y muestra los datos
        pantalla.getTblProveedores().addMouseListener(new MouseAdapter() {

            @Override
            public void mouseClicked(MouseEvent e) {
                int fila = pantalla.getTblProveedores().rowAtPoint(e.getPoint());
                experto.setProveedorSeleccionado(modeloTablaProveedores.buscarProveedor(pantalla.getTblProveedores().getValueAt(fila, 1).toString()));
                setEstadoPanelMaterialesProv(estado.OCULTAR);
                if (e.getClickCount() == 2) {
                    modificarProveedorSeleccionado();
                }
            }
        });
        //boton mostrar lista de materiales
        pantalla.getBtnMostrarListaMateriales().addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                int fila = pantalla.getTblProveedores().getSelectedRow();
                if (fila == -1) {
                    JOptionPane.showMessageDialog(pantalla, "Debe seleccinar un Proveedor.", "INFORMACIÓN", JOptionPane.INFORMATION_MESSAGE);
                } else {
                    setEstadoPanelMaterialesProv(estado.MOSTRAR);
                    mostrarListaProveedor(experto.getListaSeleccionada());
                }
            }
        });
        /***************Pantalla Modificar Proveedor*********************************/
        pantallaModificarProv.getBtnGuardar().addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                guardarProveedor();
            }
        });
        //boton cerrar 
        pantallaModificarProv.addWindowListener(new WindowAdapter() {

            @Override
            public void windowClosing(WindowEvent e) {
                pantallaModificarProv.setVisible(false);
                limpiarPantallaModiProveedor();
            }
        });
        //boton salir
        pantallaModificarProv.getBtnSalir().addActionListener(new ActionListener() {
            //TODO: REVISAR QUE AL SALIR SE HAYAN GUARDADO TODOS LOS CAMBIOS

            public void actionPerformed(ActionEvent e) {
                pantallaModificarProv.setVisible(false);
                limpiarPantallaModiProveedor();
            }
        });

        /***************Pantalla Lista Materiales Proveedor*********************************/
        pantalla.getCbxTipoMaterial().addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                filtrarMaterialesParaAgregar();
            }
        });
        pantalla.getBtnAddMaterial().addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                añadirMaterialAListaProveedor();
            }
        });
        pantalla.getBtnQuitarMaterial().addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent ae) {
                quitarMaterialListaProveedor();
            }
        });
        pantalla.getBtnGuardarLista().addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                guardarListaMaterialesProveedor();
            }
        });

        //boton nueva lista de materiales
        pantalla.getBtnNuevaLista().addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                controladorNuevaListaMateriales.iniciar();
            }
        });
        //boton buscar lista de Materiales
        pantalla.getBtnBuscarLista().addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                controladorNuevaListaMateriales.iniciar();
            }
        });

    }

    @Override
    public void iniciar() {
        try {
            pantalla.setVisible(true);
            materialesParaAgregar = ((ExpertoMateriales) FabricaExpertos.getInstancia().getExperto(FabricaExpertos.expertos.MATERIALES)).buscarMateriales(new DTOMaterial());
            modelotablaAgregarMateriales.addAllRow(materialesParaAgregar);
            modeloComboTiposMat = new ModeloComboBoxTiposMat(((ExpertoMateriales) FabricaExpertos.getInstancia().getExperto(FabricaExpertos.expertos.MATERIALES)).buscarTiposMateriales());
            pantalla.getCbxTipoMaterial().setModel(modeloComboTiposMat);
            setEstadoPanelMaterialesProv(estado.OCULTAR);
            buscarProveedores();
        } catch (ExpertoMaterialesException ex) {
            System.out.println(ex.getMessage());
        }
    }

    @Override
    public void finalizar() {
        pantalla.setVisible(false);
    }

    @Override
    public void continuar() {
        pantalla.setVisible(true);
        try {
            modelotablaAgregarMateriales.clear();
            materialesParaAgregar = ((ExpertoMateriales) FabricaExpertos.getInstancia().getExperto(FabricaExpertos.expertos.MATERIALES)).buscarMateriales(new DTOMaterial());
            modelotablaAgregarMateriales.addAllRow(materialesParaAgregar);
            modeloComboTiposMat = new ModeloComboBoxTiposMat(((ExpertoMateriales) FabricaExpertos.getInstancia().getExperto(FabricaExpertos.expertos.MATERIALES)).buscarTiposMateriales());
            pantalla.getCbxTipoMaterial().setModel(modeloComboTiposMat);
        } catch (ExpertoMaterialesException ex) {
            System.out.println(ex.getMessage());
        }
    }

    @Override
    public JInternalFrame getPantalla() {
        return pantalla;
    }

    private void buscarProveedores() {
        DTOProveedor dtoBusqueda = new DTOProveedor(pantalla.getTxtNombre().getText(), pantalla.getTxtTelefono().getText(), pantalla.getTxtCodigo().getText(), null);
        List<Proveedor> proveedoresEncontrados = null;
        try {
            proveedoresEncontrados = experto.buscarProveedores(dtoBusqueda);
        } catch (ExpertoProveedoresException ex) {
            JOptionPane.showMessageDialog(pantalla, ex.getMessage(), "MENSAJE", JOptionPane.INFORMATION_MESSAGE);
            return;
        }
        if (!modeloTablaProveedores.getListaElementos().isEmpty()) {
            modeloTablaProveedores.getListaElementos().clear();
        }
        modeloTablaProveedores.addAllRow(proveedoresEncontrados);

    }

    private void nuevoProveedor() {
        experto.clearProveedor();
        pantallaModificarProv.repaint();
        limpiarPantallaModiProveedor();
        pantallaModificarProv.setLocationRelativeTo(null);
        pantallaModificarProv.setVisible(true);
    }

    private void modificarProveedorSeleccionado() {
        pantallaModificarProv.repaint();
        mostrarProveedor();
        pantallaModificarProv.setLocationRelativeTo(null);
        pantallaModificarProv.setVisible(true);

    }

    private void guardarProveedor() {
        DTOProveedor dtoProv = new DTOProveedor();
        dtoProv.setCodigo(pantallaModificarProv.getTxtCodigoProveedor().getText());
        dtoProv.setNombre(pantallaModificarProv.getTxtNombreProveedor().getText());
        dtoProv.setDireccion(pantallaModificarProv.getTxtDireccion().getText());
        dtoProv.setTelefono(pantallaModificarProv.getTxtTelefono().getText());
        if (experto.getProveedorSeleccionado() == null) {
            experto.crearProveedor(dtoProv);
        } else {
            experto.modificarProveedorSeleccionado(dtoProv);
        }

        try {
            experto.guardarProveedor();
        } catch (ExpertoProveedoresException ex) {
            JOptionPane.showMessageDialog(pantalla, "ERROR al guardar nuevo proveedor", "ERROR", JOptionPane.ERROR_MESSAGE);
        }
        modeloTablaProveedores.quitarProveedorLista(experto.getProveedorSeleccionado());
        modeloTablaProveedores.addRow(experto.getProveedorSeleccionado());
        pantallaModificarProv.setVisible(false);

    }

    private void eliminarProveedor() {
        if (experto.getProveedorSeleccionado() != null) {
            int seleccion = JOptionPane.showOptionDialog(
                    null,
                    "Esta seguro que desea eliminar Proveedor: " + experto.getProveedorSeleccionado().getNombre(),
                    "ELIMINAR PROVEEDOR",
                    JOptionPane.YES_NO_OPTION,
                    JOptionPane.QUESTION_MESSAGE,
                    null, // null para icono por defecto.
                    new Object[]{"Aceptar", "Cancelar"}, // null para YES, NO y CANCEL
                    "Cancelar");
            if (seleccion == 0) {
                try {
                    experto.eliminarProveedorSeleccionado();
                } catch (ExpertoProveedoresException ex) {
                    JOptionPane.showMessageDialog(pantalla, ex.getMessage() + "\nEl proveedor seleccionado no ha sido eliminado", "ERROR", JOptionPane.ERROR_MESSAGE);
                }
                modeloTablaProveedores.quitarProveedorLista(experto.getProveedorSeleccionado());
            }
        }
    }

    private void limpiarPantallaModiProveedor() {
        for (Component component : pantallaModificarProv.getComponents()) {
            if (component instanceof JTextField) {
                ((JTextField) component).setText("");
            }
        }
    }

    private void mostrarProveedor() {
        if (experto.getProveedorSeleccionado() != null) {
            pantallaModificarProv.getTxtCodigoProveedor().setText(experto.getProveedorSeleccionado().getCodigoProveedor());
            pantallaModificarProv.getTxtDireccion().setText(experto.getProveedorSeleccionado().getDireccion());
            pantallaModificarProv.getTxtNombreProveedor().setText(experto.getProveedorSeleccionado().getNombre());
            pantallaModificarProv.getTxtTelefono().setText(experto.getProveedorSeleccionado().getTelefono());
        }
    }

    /**
     * Muestra en pantalla la lista de materiales enviada en el parametro lista, si es null, borra los datos que hay en pantalla;
     * @param lista 
     */
    public void mostrarListaProveedor(ListaMateriales lista) {
        pantalla.getLblNombreProveedor().setText(experto.getProveedorSeleccionado().getNombre());
//        experto.setListaSeleccionada(lista);
        if (lista == null) {
            pantalla.getLblFechaListaMat().setText("El proveedor seleccionado no posee lista de materialeas actualmente");
            pantalla.getLblFechaListaMat().setForeground(Color.red);
            pantalla.getLblFechaModificacionLista().setText(null);
            pantalla.getLblCodigoLista().setText(null);
            modeloTablaListaMateriales.clear();
            return;
        }
        ((ModeloTablaListaMateriales) pantalla.getTblListaMateriales().getModel()).setListaElementos(lista.getDetallelistamaterialesList());
        pantalla.getLblFechaModificacionLista().setText(formateadorfechas.getFormat_dd_MM_yyyy().format(lista.getFechaModificacion()));
        pantalla.getLblFechaListaMat().setText(formateadorfechas.getFormat_dd_MM_yyyy().format(lista.getFechainiciolistamateriales()));
        pantalla.getLblFechaListaMat().setForeground(new Color(13, 140, 243));
        pantalla.getLblCodigoLista().setText(lista.getId().toString());

    }

    //filtra la lista de los materiales que se pueden agregar
    private void filtrarMaterialesParaAgregar() {
        if (pantalla.getCbxTipoMaterial().getSelectedIndex() == 0) {
            modelotablaAgregarMateriales.clear();
            modelotablaAgregarMateriales.setListaElementos(materialesParaAgregar);
            return;
        }
        List<Material> materialesFiltrados = new ArrayList<Material>();
        for (Material material : materialesParaAgregar) {
            if (material.getTipoMaterial().getNombretipomaterial().equals(modeloComboTiposMat.getTipoSeleccionado().getNombretipomaterial())) {
                materialesFiltrados.add(material);
            }
        }
        modelotablaAgregarMateriales.clear();
        modelotablaAgregarMateriales.setListaElementos(materialesFiltrados);
    }

    /**
     * Añade un nuevo material a la lista de materiales del proveedor
     */
    private void añadirMaterialAListaProveedor() {
        int col, row;
        col = pantalla.getTblMateriales().getSelectedColumn();
        row = pantalla.getTblMateriales().getSelectedRow();
        if (modelotablaAgregarMateriales.getMaterial(pantalla.getTblMateriales().getValueAt(row, col).toString()) == null) {// contrla si no hay material seleccionado
            return;
        }
        //material seleccionado
        Material material = modelotablaAgregarMateriales.getMaterial(pantalla.getTblMateriales().getValueAt(row, col).toString());
        //busca si el material seleccinado esta en la lista
        experto.agregarMaterialListaSeleccinada(material);
        modeloTablaListaMateriales.setListaElementos(experto.getListaSeleccionada().getDetallelistamaterialesList());
    }

    private void quitarMaterialListaProveedor() {

        int row;

        row = pantalla.getTblListaMateriales().getSelectedRow();
        if (modeloTablaListaMateriales.getListaElementos().get(row) == null) {// contrla si no hay material seleccionado
            return;
        }
        //material seleccionado
        Material material = ((DetalleListaMateriales) modeloTablaListaMateriales.getListaElementos().get(row)).getMaterial();
        //modeloTablaListaMateriales.removeElement(material);
        //busca si el material seleccinado esta en la lista
        experto.quitarMaterialListaSeleccionada(material);
        modeloTablaListaMateriales.fireTableDataChanged();
    }

    //TODO: mostrar mensajes de que se guardo con exito la lista, hacer lo mismo al guardar el proveedor
    /**
     * Guarda la lista de materiales seleccionada
     */
    private void guardarListaMaterialesProveedor() {
        //listaMaterialesProveedor.setDetallelistamaterialesList(modeloTablaListaMateriales.getListaElementos());
        try {
            experto.guardarListaMateriales(experto.getListaSeleccionada());
        } catch (ExpertoProveedoresException ex) {
            JOptionPane.showMessageDialog(pantalla, ex.getMessage(), "ERROR", JOptionPane.WARNING_MESSAGE);
        }
        JOptionPane.showMessageDialog(pantalla, "Lista guardada correctamente", "INFORMACION", JOptionPane.INFORMATION_MESSAGE);
    }

    private enum estado {

        OCULTAR, MOSTRAR
    }

    private void setEstadoPanelMaterialesProv(estado estadoPanel) {
        switch (estadoPanel) {
            case OCULTAR:
                if (pantalla.getjTabbedPaneProveedores().getComponents().length == 1) {
                    return;
                }
                respaldoJtabbed = pantalla.getjTabbedPaneProveedores().getComponentAt(1);
                pantalla.getjTabbedPaneProveedores().removeTabAt(1);
                break;
            case MOSTRAR:
                pantalla.getjTabbedPaneProveedores().add("Materiales", respaldoJtabbed);
                pantalla.getjTabbedPaneProveedores().setSelectedComponent(pantalla.getjTabbedPaneProveedores().getComponentAt(1));
                break;

        }

    }
}
